#! /usr/bin/env python
# -*- coding: utf-8 -*-
#AutoRename.py



import os
import glob
from shutil import copy



class AutoRename(object):
    
    def __init__(self, sourcepath, targetpath, suffix):
        '''This will execute all needed functions and output them.'''
        
        files = self.findFiles(sourcepath, suffix)
        self.moveFiles(targetpath, files)
        self.renameFiles(targetpath, suffix)
        self.logIt('You can find all changes logged in the textfile !_LOG_! '
                   'inside your targetfolder')

        
    def findFiles(self, sourcepath, suffix):
        '''Returns all files in the sourcepath directory ending with suffix.'''
        
        os.chdir(sourcepath)
        files = glob.glob('*{0}'.format(suffix))
        return files
        
    
    def moveFiles(self, targetpath, files):
        '''Simply copies all files to the targetpath.'''
        
        for entry in files:
            copy(entry, targetpath)


    def renameFiles(self, targetpath, suffix):
        '''Renames the text files.

        Renames the files accodingly to their first 20 words.
        Removes any special characters.'''
        
        all_delete = ([])
        special = '\\/:*?"<>\t'
        namecounter, errorcounter, linecounter = 0, 0, 0
        os.chdir(targetpath)
        all_entries = glob.glob('*')
        all_dict = dict(zip(all_entries, all_entries))
        for entry in all_entries:
            with open(entry, 'r') as f:
                first_line = f.readline().strip().translate(None, special)
                if first_line == '':
                    all_delete += [entry]
                    del all_dict[entry]
                    continue
                elif first_line[0:20] in all_dict.values():
                    newname = '{0}_{1}'.format(first_line[0:20], namecounter)
                    all_dict[entry] = newname
                    namecounter += 1
                else:
                    all_dict[entry] = first_line[0:20]
            try:
                os.rename(entry, all_dict[entry] + suffix)
            except OSError as (errno, strerror):
                newname = '.Error_{0}'.format(errorcounter)
                oldname = all_dict[entry] + '.txt'
                all_dict[entry] = newname
                os.rename(entry, all_dict[entry] + '.txt')
                self.logIt("{0}   '{1}' is now labeled as '{2}' instead of "
                           "'{3}'".format(linecounter, entry,
                                          newname, oldname))
                self.logIt('    OSError {0}: {1}\n'.format(errno, strerror))
                errorcounter += 1
                linecounter += 1
            else:
                self.logIt("{0}   '{1}' is now labeled as '{2}'".\
                      format(linecounter, entry, all_dict[entry]))
            linecounter += 1
        for entry in all_delete:
            os.remove(entry)
            self.logIt("{0}   '{1}' has been deletet because it had "
                       "no content".format(linecounter, entry))
            linecounter += 1
                
        successful = linecounter - errorcounter
        self.logIt('{0} of {1} operations were successful'.format(successful,
                                                             linecounter))
    
    
    def logIt(self, message):
        '''Loggs and prints simultaneously

        The log is written to !_LOG_!.txt.'''
        
        with open('!_LOG_!.txt', 'a') as logfile:
            logfile.write(message + '\n')
        print message

        
if __name__ == '__main__':
    sourcepath = '/home/sheepherd/Desktop/Source'
    targetpath = '/home/sheepherd/Desktop/Target'
    suffix = '.txt'
    AutoRename(sourcepath, targetpath, suffix)
    